<template>
  <!-- TypeSelection 分类选择 -->
  <view>
    <Header title="分类选择" v-model="headerHeight" :is-box-shadow="false" />
    <view class="container" :style="{ height: `calc(100vh - ${headerHeight + 1}px)` }">
      <scroll-view class="type-title" scroll-y enhanced :show-scrollbar="false" enable-passive>
        <template v-for="(item, index) in typeList" :key="index">
          <view
            :class="[
              'type-title--item',
              'text-overflow-1',
              current === index && 'type-title--item__active',
            ]"
            @click="typeTitleItemClick(index)"
          >
            <text :class="[item.num && 'type-title--text']" :data-attr="item.num">
              {{ item.name }}
            </text>
          </view>
        </template>
      </scroll-view>
      <view class="right">
        <scroll-view class="right-scroll" scroll-y enhanced :show-scrollbar="false" enable-passive>
          <view class="type-child">
            <template v-for="(v, i) in childs" :key="i">
              <view
                :class="[
                  'type-child--item',
                  'text-overflow-1',
                  hasSelected(v.id) !== -1 && 'type-child--item__active',
                ]"
                @click="childClick(v.id, v.name)"
              >
                <text>{{ v.name }}</text>
              </view>
            </template>
          </view>
        </scroll-view>
        <view v-if="!isRadio" class="btn-group">
          <button class="btn rest" type="none" @click="rest">重置</button>
          <button class="btn submit" type="primary" @click="submit">保存</button>
        </view>
      </view>
    </view>
  </view>
</template>

<script lang="ts" setup>
  /**  TypeSelection  分类选择 */
  import { getClassTypeList } from '@/api';
  import { type ClassTypeListKey, type ClassTypeListResult } from '@/api/indexTypes';
  import Header from '@/components/Header/index.vue';
  import { navigateBack, onLoad } from '@/router';
  import { type TypeSelectedItem, type TypeSelection } from '@/router/types/modules';
  import { isNullOrUnDef } from '@/utils/is';
  import { findIndex, has } from 'lodash-es';
  import { ref, unref } from 'vue';

  interface TypeDataInter extends ClassTypeListResult {
    num: number;
  }

  const headerHeight = ref(0);
  const typeList = ref<TypeDataInter[]>([]);
  const childs = ref<ClassTypeListResult['list']>([]);
  const selected = ref<TypeSelectedItem[]>([]);
  const current = ref(0);
  const typeKeys = ref<ClassTypeListKey[]>([]);
  const isRadio = ref<boolean>();
  let success: TypeSelection['success'];

  onLoad<'TypeSelection'>(async (op) => {
    typeKeys.value = op.keys || [];
    selected.value = op.selected || [];
    isRadio.value = op.isRadio;
    success = op.success;
    const data = op.localData || (await getClassTypeList(unref(typeKeys)));
    op.isRadio ? setRadioData(data) : setMultipleData(data);
  });

  function setMultipleData(data: ClassTypeListResult[]) {
    childs.value = data[0].list;
    const selectedLength = unref(selected).length;
    let numArr: Recordable<number> = {};
    if (selectedLength) {
      numArr = unref(selected).reduce((result, val) => {
        result[val.key] = has(result, val.key) ? result[val.key] + 1 : 1;
        return result;
      }, {} as Recordable<number>);
    }
    typeList.value = data.map((v) => {
      return { ...v, num: selectedLength ? numArr[v.key] : 0 };
    });
  }

  function setRadioData(data: ClassTypeListResult[]) {
    const item = unref(selected)[0];
    typeList.value = data.map((v) => ({ ...v, num: 0 }));
    if (item) {
      const selectedIndex = unref(typeList).findIndex((v) => v.key === item.key);
      current.value = selectedIndex === -1 ? 0 : selectedIndex;
      typeList.value[selectedIndex].num = 1;
      childs.value = data[selectedIndex].list;
    } else {
      childs.value = data[0].list;
    }
  }

  function typeTitleItemClick(index: number) {
    current.value = index;
    childs.value = unref(typeList)[index].list;
  }

  function childClick(id: number | string, name: string) {
    const index = unref(current);
    const item = unref(typeList)[index];
    if (unref(isRadio)) {
      selected.value = id === 0 ? [] : [{ key: item.key, id, name }];
      submit();
      return;
    }
    const childIndex = hasSelected(id);
    if (childIndex !== -1) {
      item.num = computedNum(item.num, 'subtract');
      selected.value.splice(childIndex, 1);
    } else {
      item.num = computedNum(item.num, 'add');
      selected.value.push({ key: item.key, id, name });
    }
  }

  function computedNum(num: number, type: 'add' | 'subtract') {
    if (isNullOrUnDef(num)) num = 0;
    if (type === 'subtract') {
      return num > 0 ? num - 1 : 0;
    } else {
      return num < 99 ? num + 1 : 99;
    }
  }

  function hasSelected(id: number | string, index: number = unref(current)) {
    const key = unref(typeList)[index].key;
    return findIndex(unref(selected), (v) => v.key === key && v.id === id);
  }

  function rest() {
    unref(typeList).forEach((v) => (v.num = 0));
    selected.value = [];
  }
  function submit() {
    success?.(unref(selected));
    navigateBack();
  }
</script>

<style lang="scss" scoped>
  .container {
    width: 100vw;
    display: flex;
    background-color: #fff;
    border-top: 1px solid #eee;
    position: relative;
    .type-title {
      width: 260rpx;
      flex-shrink: 0;
      height: inherit;
      border-right: 1px solid #eee;
      &--item {
        height: 88rpx;
        text-align: center;
        line-height: 88rpx;
        font-size: 28rpx;
        color: #000;
        background-color: #fff;
        transition: all 0.3s;

        &__active {
          background-color: #f5f5f5;
        }
      }
      &--text {
        position: relative;
        &::before {
          content: attr(data-attr);
          position: absolute;
          top: -14rpx;
          right: -28rpx;
          width: 28rpx;
          height: 28rpx;
          text-align: center;
          line-height: 28rpx;
          color: #fff;
          background-color: #ff3434;
          border-radius: 50%;
          font-size: 20rpx;
        }
      }
    }
    .right {
      flex: 1;
      // display: flex;
      // flex-direction: column;
      &-scroll {
        height: calc(100% - 88rpx - 60rpx - env(safe-area-inset-bottom));
        margin-bottom: 30rpx;
      }
      .btn-group {
        height: 88rpx;
        margin-bottom: 30rpx;
        display: grid;
        grid-template-columns: repeat(auto-fit, 214rpx);
        grid-row-gap: 30rpx;
        justify-content: space-evenly;
        align-content: center;
        .btn {
          height: 88rpx;
          line-height: 88rpx;
          border-radius: 20rpx;
          font-size: 28rpx;
          &.rest {
            color: #2878ff;
            border: 1px solid #2878ff;
          }
        }
      }
    }
    .type-child {
      padding-top: 30rpx;
      display: grid;
      grid-template-columns: repeat(auto-fit, 214rpx);
      grid-row-gap: 30rpx;
      justify-content: space-evenly;
      align-content: center;
      &--item {
        height: 60rpx;
        background: #f5f5f5;
        border-radius: 10rpx;
        font-size: 28rpx;
        color: #000;
        text-align: center;
        line-height: 60rpx;
        &__active {
          background-color: #d0f7ff;
          color: #2878ff;
        }
      }
    }
  }
</style>
